//=============================================================================
// EXECUTABLE 'VIRTUALDISK'
//=============================================================================
// per Marc Delgado (marcdelgado@gmail.com) | rev. 2012.06.11

#include <iostream>
#include <string>
#include <list>
#include "filemanager.hpp"
using namespace std;

//VARIABLES GLOBALS I FUNCIONS
string str1, str2, str3, str4, str5, str6, str7, str8;  //Parametres d'entrada.
int codi; unsigned char tipus, mr, mcc;                 //Parametres numerables.
char *comanda, *fitxer, *clau, *altres;                 //Parametres text.
void importParams();                                    //Normalitza els paràmetres.
void printExec();                                       //Mostra l'execució actual.

// FUNCIO PRINCIPAL
///////////////////////////////////////////////////////////////////////////////


int main()
{
        fileManager fman((char*)"disc");

        //BUCLE D'EXECUCIO DE COMANDES
        while(!cin.eof())
        {
            //Rebem els parametres i els importem a les variables amb format correcte.
            cin >> str1 >> str2 >> str3 >> str4 >> str5 >> str6 >> str7 >> str8;
            importParams();

            if(str2.size() > 0)
            {
                printExec();
                //ACCIO CREAR FITXER
                if(comanda == string("crearf"))
                {
                    //Comprovem mides de registre i clau.
                    if(mcc >= mr or mr > 255)
                        cout << "[" << codi << "] " << "ERROR: mida de clau o registre, incoherent." << endl;
                    //Si els parametres son coherents, intentem crear fitxer.
                    else{
                        bool ok = fman.crearf(fitxer, tipus, mr, mcc);
                        if (ok) cout << "[" << codi << "] " << "FET: fitxer creat amb exit." << endl;
                        else cout << "[" << codi << "] " << "ERROR: el fitxer ja existeix." << endl;
                    }
                }


                //ACCIO ESBORRAR FITXER
                else if(comanda == string("delf"))
                {
                    bool ok = fman.delf(fitxer);
                    if(ok) cout << "[" << codi << "] " << "FET: fitxer esborrat." << endl;
                    else cout << "[" << codi << "] " << "ERROR: no existeix el fitxer." << endl;
                }


                //ACCIO INSERIR REGISTRE
                else if(comanda == string("insertr"))
                {
                    bool ok = fman.insertr(fitxer, clau, altres);
                    if(ok) cout << "[" << codi << "] " << "FET: registre inserit amb exit." << endl;
                    else cout << "[" << codi << "] " << "ERROR: fitxer no valid o registre ja existeix." << endl;
                }


                //ACCIO ESBORRAR REGISTRE
                else if(comanda == string("delr"))
                {
                    bool ok = fman.delr(fitxer, clau);
                    if(ok) cout << "[" << codi << "] " << "FET: registre esborrat amb exit." << endl;
                    else cout << "[" << codi << "] " << "ERROR: fitxer no valid o registre no existeix." << endl;
                }


                //ACCIO CERCAR RANG
                else if(comanda == string("query"))
                {
                    if (tipus != 3) cout << "[" << codi << "] " << "ERROR: aquesta indexacio no esta implementada." << endl;
                    else
                    {
                        pair<list<char*>,int> rang = fman.query(fitxer, tipus, clau, altres);
                        int mida = rang.second;
                        cout<< "[" << codi << "] " << "FET: mostrant resultat..." << endl;
                        while(!rang.first.empty())
                        {
                            cout << "CLAU: ";
                            for (int i = 0; i < mida; i++) cout << rang.first.back()[i];
                            cout << "VALOR: ";
                            for (int i = 0; i < 16; i++) cout << rang.first.back()[mida+i];
                            cout << "..." << endl;
                            rang.first.pop_back();
                        }
                    }
                }
                //ERROR DE SINTAXI
                else cout << "ERROR: sintaxi no reconeguda." << endl;
            }
            str2 = "";

        }
        cout << endl << "EXECUCIO FINALITZADA" << endl << endl;
        cout.flush();
}


// FUNCIONS AUXILIARS
///////////////////////////////////////////////////////////////////////////////


void importParams()
{
    //codi
    codi = atoi(str1.c_str());
    //comanda
    comanda = (char*)str2.c_str();
    //fitxer
    fitxer = (char*)str3.c_str();
    //tipus
    tipus = atoi(str4.c_str());
    //mr
    mr = atoi(str5.c_str());
    //mcc
    mcc = atoi(str6.c_str());
    //clau
    clau = (char*)str7.c_str();
    //altres
    altres = (char*)str8.c_str();
}


void printExec()
{
    cout << "[" << (int)codi << "] " << "ORDRE: " << " " << comanda << " " << fitxer;
    cout << " " << (int)tipus << " " << (int)mr << " " << (int)mcc << " " << clau << " ";
    for(unsigned int i = 0; (i < 16) and altres[i] != 0; i++) cout << altres[i];
    cout << "..." << endl;
}
